package forum;

import cms.bean.install.Install;
import cms.utils.*;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;

/**
 * 安装数据库
 */
public class Init {

    public static void main(String[] args) {
        String userAccount = "admin";//管理员账号
        String userPassword = "1234567";//管理员密码

        Connection conn = null;
        ResultSet rs = null;
        Statement stmt = null;
        try {
            conn = getConnection();

            //通过查询运行设置字符集的命令
            rs = conn.prepareStatement("show variables like 'char%'").executeQuery();

            String character_set_database = "";

            while (rs.next()) if ("character_set_database".equalsIgnoreCase(rs.getString(1))) character_set_database = rs.getString(2);

            if (!"utf8mb4".equalsIgnoreCase(character_set_database)) throw new RuntimeException("数据库必须为utf8mb4编码");

            //通过查询运行设置字符集的命令
            conn.prepareStatement("set names utf8mb4").executeQuery();
            String user_dir = System.getProperty("user.dir");
            String path = user_dir + File.separator + "src" + File.separator + "main" + File.separator + "webapp" + File.separator + "WEB-INF" + File.separator + "data" + File.separator + "install" + File.separator;

            //导入SQL结构文件
            SqlFile.importSQL(conn, path + "structure_tables_mysql.sql", "utf-8");

            //导入SQL数据文件
            SqlFile.importSQL(conn, path + "data_tables_mysql.sql", "utf-8");

            //插入管理员数据
            PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();//BCrypt密码算法,Bcrypt加密最长为72个字符，超过72字符的部分被截断丢弃了

            // 密码通过盐值加密以备存储入数据库
            String newPassword = passwordEncoder.encode(SHA.sha256Hex(userPassword.trim()));

            String sql = "INSERT INTO `sysusers` (`userId`,`enabled`,`fullName`,`issys`,`securityDigest`,`userAccount`,`userDesc`,`userDuty`,`userPassword`) VALUES ('" + UUIDUtil.getUUID32() + "',b'1','" + userAccount.trim() + "',b'1','" + UUIDUtil.getUUID32() + "','" + userAccount.trim() + "',NULL,'管理员','" + newPassword + "')";

            stmt = conn.createStatement();
            stmt.executeUpdate(sql);
            conn.commit();

            System.out.println("导入数据完成");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    }

    /**
     * 获取数据库连接
     */
    private static Connection getConnection() throws Exception {
        Install install = getDatabaseParameter();

        //linux下5.7必须加这句,不然会报错java.sql.SQLException: No suitable driver found for
        DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());//注册驱动

        return DriverManager.getConnection(install.getDatabaseURL().trim(), install.getDatabaseUser().trim(), install.getDatabasePassword().trim());
    }

    /**
     * 获取数据库参数
     */
    private static Install getDatabaseParameter() {
        Install install = new Install();

        //读取数据库配置文件
        InputStream in = null;

        CommentedProperties database_props = new CommentedProperties();
        //数据库连接地址
        String jdbc_url;
        //数据库用户名
        String jdbc_user;
        //数据库密码密文
        String jdbc_password_ciphertext;
        //数据库密码原文
        String jdbc_password_original;
        //公钥参数组
        String jdbc_publicKey;
        try {
            String user_dir = System.getProperty("user.dir");
            String path = user_dir + File.separator + "src" + File.separator + "main" + File.separator + "resources" + File.separator + "druid.properties";

            in = new FileInputStream(path);

            database_props.load(in, "utf-8");

            jdbc_url = database_props.getProperty("jdbc_url");
            jdbc_user = database_props.getProperty("jdbc_user");
            jdbc_password_ciphertext = database_props.getProperty("jdbc_password");
            jdbc_publicKey = database_props.getProperty("jdbc_publickey");

            if (jdbc_password_ciphertext != null && !"".equals(jdbc_password_ciphertext.trim())) {
                if (jdbc_publicKey != null && !"".equals(jdbc_publicKey.trim())) {

                    String publickey = null;
                    String[] jdbc_publicKey_group = jdbc_publicKey.split(";");
                    if (jdbc_publicKey_group.length > 0) for (String str : jdbc_publicKey_group)
                        if (str.startsWith("config.decrypt.key")) publickey = str.substring(19);

                    //解密
                    jdbc_password_original = DruidTool.decryptString(publickey, jdbc_password_ciphertext);
                } else {
                    jdbc_password_original = jdbc_password_ciphertext;
                }
            } else {
                jdbc_password_original = jdbc_password_ciphertext;
            }


            install.setDatabaseUser(jdbc_user);//数据库用户名
            install.setDatabasePassword(jdbc_password_original);//数据库密码
            install.setDatabaseURL(jdbc_url);//数据库连接地址
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return install;
    }

}
